﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Diagnostics;

namespace eda12136309
{
    public partial class Form1 : Form
    {
        private const int SIZE = 20000;

        public Form1()
        {
            InitializeComponent();
        }

        private void button_start_Click(object sender, EventArgs e)
        {
            int[] array = this.generateRandomArray();

            int[] array1 = new int[SIZE];
            int[] array_result = new int[SIZE];

            textBox_output.Text = "A começar o programa..." + Environment.NewLine;

            this.runAlgorithms(array, array1, array_result);

            textBox_output.Text += "Fim do programa!";

            if (checkBox_printToFile.Checked)
            {
                System.IO.StreamWriter file = new System.IO.StreamWriter("output.txt");
                file.WriteLine(textBox_output.Text);

                file.Close();

                MessageBox.Show("Output guardado no ficheiro output.txt");
            }
        }

        private int[] generateRandomArray()
        {
            List<int> list = new List<int>(SIZE);

            for (int i = 0; i < SIZE; i++)
            {
                list.Add(i + 1);
            }

            this.Shuffle<int>(list);

            return list.ToArray();
        }

        // http://stackoverflow.com/questions/273313/randomize-a-listt-in-c-sharp
        private void Shuffle<T>(IList<T> list)
        {
            Random rng = new Random((int)System.DateTime.Now.Ticks);
            int n = list.Count;
            while (n > 1)
            {
                n--;
                int k = rng.Next(n + 1);
                T value = list[k];
                list[k] = list[n];
                list[n] = value;
            }
        }

        private void runAlgorithms(int[] array, int[] array1, int[] array_result)
        {
            Stopwatch sw = new Stopwatch();

            for (int i = 0; i < numericUpDown_algorithmRepeatNumber.Value; i++)
            {
                if (checkedListBox_algorithmSelection.GetItemCheckState(0).ToString() == "Checked")
                {
                    array1 = copyArray(array);
                    sw.Start();
                    array_result = AlgorithmLibrary.insertionSort(array1);
                    sw.Stop();

                    textBox_output.Text += String.Format("Duração do InsertionSort({0}): {1}{2}", i, sw.Elapsed, Environment.NewLine);

                    sw.Reset();
                    array1 = null;
                }

                if (checkedListBox_algorithmSelection.GetItemCheckState(1).ToString() == "Checked")
                {
                    array1 = copyArray(array);
                    sw.Start();
                    array_result = AlgorithmLibrary.bubbleSort(array1);
                    sw.Stop();

                    textBox_output.Text += String.Format("Duração do BubbleSort({0}): {1}{2}", i, sw.Elapsed, Environment.NewLine);

                    sw.Reset();
                    array1 = null;
                }

                if (checkedListBox_algorithmSelection.GetItemCheckState(2).ToString() == "Checked")
                {
                    array1 = copyArray(array);
                    sw.Start();
                    array_result = AlgorithmLibrary.heapSort(array1);
                    sw.Stop();

                    textBox_output.Text += String.Format("Duração do HeapSort({0}): {1}{2}", i, sw.Elapsed, Environment.NewLine);

                    sw.Reset();
                    array1 = null;
                }

                if (checkedListBox_algorithmSelection.GetItemCheckState(3).ToString() == "Checked")
                {
                    array1 = copyArray(array);
                    sw.Start();
                    array_result = AlgorithmLibrary.mergeSort(array1, 0, array1.Length - 1);
                    sw.Stop();

                    textBox_output.Text += String.Format("Duração do MergeSort({0}): {1}{2}", i, sw.Elapsed, Environment.NewLine);

                    sw.Reset();
                    array1 = null;
                }

                if (checkedListBox_algorithmSelection.GetItemCheckState(4).ToString() == "Checked")
                {
                    array1 = copyArray(array);
                    sw.Start();
                    array_result = AlgorithmLibrary.quickSort(array1, 0 , array1.Length - 1);
                    sw.Stop();

                    textBox_output.Text += String.Format("Duração do QuickSort({0}): {1}{2}", i, sw.Elapsed, Environment.NewLine);

                    sw.Reset();
                    array1 = null;
                }
            }
        }

        private int[] copyArray(int[] A)
        {
            int[] B = new int[A.Length];

            for (int i = 0; i < A.Length; i++)
            {
                B[i] = A[i];
            }

            return B;
        }

        private void printArray(int[] A)
        {
            for (int i = 0; i < A.Length; i++)
            {
                Console.WriteLine(A[i]);
            }
        }
    }
}
